package com.msh.artascope.devcloud.service.service.impl;


import com.alibaba.fastjson.JSON;
import com.msh.artascope.devcloud.client.enums.biz.HealthTestProbeModeEnum;
import com.msh.artascope.devcloud.client.enums.biz.HealthTestProbeModeEnum.ExecTest;
import com.msh.artascope.devcloud.client.enums.biz.HealthTestProbeModeEnum.HttpTest;
import com.msh.artascope.devcloud.client.enums.biz.HealthTestProbeModeEnum.TcpTest;
import com.msh.artascope.devcloud.service.model.page.ModuleHealthTestVo;
import com.msh.artascope.devcloud.service.service.ModuleService;
import com.msh.artascope.devcloud.client.enums.biz.HealthTestTypeEnum;
import com.msh.artascope.devcloud.service.dao.HealthTestDao;
import com.msh.artascope.devcloud.service.model.query.HealthTestQueryVo;
import com.msh.artascope.devcloud.service.model.vo.HealthTestVo;
import com.msh.frame.client.base.TenantBaseServiceImpl;
import com.msh.frame.client.exception.BizException;
import javax.annotation.Resource;

import com.msh.frame.interfaces.IdGenerateable;
import com.msh.artascope.devcloud.client.po.HealthTestPo;
import com.msh.artascope.devcloud.client.qo.HealthTestQo;
import com.msh.artascope.devcloud.service.service.HealthTestService;
import com.msh.frame.client.common.Result;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import org.springframework.util.CollectionUtils;

/**
 * @author shihu
 * @mail m-sh@qq.com
 */
@Service
@Slf4j
public class HealthTestServiceImpl extends TenantBaseServiceImpl<HealthTestPo,HealthTestQo> implements HealthTestService {

  @Resource
  private ModuleService moduleService;

  @Resource
  private HealthTestDao healthTestDao;

  @Resource
  private IdGenerateable idGenerateable;

  @Override
  public long insert(HealthTestPo param) {
    param.setId(idGenerateable.getUniqueId());
    return super.insert(param);
  }

  @Override
  public int insertCollection(Collection<HealthTestPo> param) {
    param.stream().forEach(p->p.setId(idGenerateable.getUniqueId()));
    return super.insertCollection(param);
  }

  /**
   * 设置检测参数
   * @param healthTestVo
   */
  private void setProbeParam(HealthTestVo healthTestVo){
    String probeMode = healthTestVo.getProbeMode();
    if(HealthTestProbeModeEnum.HTTP.getCode().equals(probeMode)){
      HttpTest httpTest = healthTestVo.getHttpTest();
      BizException.doThrowIfNull("缺少http测试参数", httpTest);
      healthTestVo.setProbeParam(JSON.toJSONString(httpTest));
    }else if(HealthTestProbeModeEnum.TCP.getCode().equals(probeMode)){
      TcpTest tcpTest = healthTestVo.getTcpTest();
      BizException.doThrowIfNull("缺少tcp测试参数", tcpTest);
      healthTestVo.setProbeParam(JSON.toJSONString(tcpTest));
    }else if(HealthTestProbeModeEnum.EXEC.getCode().equals(probeMode)){
      ExecTest execTest = healthTestVo.getExecTest();
      BizException.doThrowIfNull("缺少exec测试参数", execTest);
      healthTestVo.setProbeParam(JSON.toJSONString(execTest));
    }
  }

  @Override
  public long insertVo(HealthTestVo healthTestVo) {
    setProbeParam(healthTestVo);
    return insert(healthTestVo);
  }

  @Override
  public void updateVo(HealthTestVo healthTestVo) {
    setProbeParam(healthTestVo);
    update(healthTestVo);
  }

  @Override
  public ModuleHealthTestVo moduleHealthTest(Long moduleId, Long tenantId) {
    ModuleHealthTestVo moduleHealthTestVo = new ModuleHealthTestVo();
    HealthTestQueryVo healthTestQueryVo = new HealthTestQueryVo();
    healthTestQueryVo.setModuleId(moduleId).setTenantId(tenantId);
    this.listVo(healthTestQueryVo)
      .stream()
      .forEach(vo->{
        if(HealthTestTypeEnum.READY.getCode().equals(vo.getType())){
          moduleHealthTestVo.setReady(vo);
        }
        if(HealthTestTypeEnum.LIVE.getCode().equals(vo.getType())){
          moduleHealthTestVo.setLive(vo);
        }
      });
    ;
    return moduleHealthTestVo;
  }


// ----------前端vo处理-------------------------------------------------------

  private HealthTestVo toVo(HealthTestPo po){
    HealthTestVo vo = po.convert(HealthTestVo.class);
    String probeMode = vo.getProbeMode();
    String probeParam = vo.getProbeParam();
    if(HealthTestProbeModeEnum.HTTP.getCode().equals(probeMode)){
      vo.setHttpTest(JSON.parseObject(probeParam, HealthTestProbeModeEnum.HttpTest.class));
    }else if(HealthTestProbeModeEnum.TCP.getCode().equals(probeMode)){
      vo.setTcpTest(JSON.parseObject(probeParam, HealthTestProbeModeEnum.TcpTest.class));
    }else if(HealthTestProbeModeEnum.EXEC.getCode().equals(probeMode)){
      vo.setExecTest(JSON.parseObject(probeParam, HealthTestProbeModeEnum.ExecTest.class));
    }
    return vo;
  }

  private List<HealthTestVo> toVoList(List<HealthTestPo> list){
    if(CollectionUtils.isEmpty(list)){
      return Collections.emptyList();
    }

    return list.stream().map(po->{
      return toVo(po);
    }).collect(Collectors.toList());
  }

  @Override
  public HealthTestVo getVo(Long id, Long tenantId) {
    HealthTestPo po = this.get(id, tenantId);
    if(null == po){
      return null;
    }
    HealthTestVo vo = toVo(po);

    return vo;
  }

  @Override
  public List<HealthTestVo> listVo(HealthTestQueryVo q){
    HealthTestQo qo = q.convert(HealthTestQo.class);
    List<HealthTestPo> poList = this.list(qo);
    List<HealthTestVo> voList = toVoList(poList);

    return voList;
  }

  @Override
  public Result<List<HealthTestVo>> pageVo(HealthTestQueryVo param) {
    HealthTestQo qo = param.convert(HealthTestQo.class);
    int count = this.count(qo);
    if (0 == count) {
      return Result.successReturn(Collections.<HealthTestVo>emptyList()).setCount(count);
    }
    List<HealthTestPo> poList = this.list(qo);
    List<HealthTestVo> voList = toVoList(poList);

    return Result.successReturn(voList).setCount(count);
  }


}
